package com.lifeverse.service;

import com.lifeverse.entity.Rule;
import com.lifeverse.entity.enums.RulePriority;
import com.lifeverse.repository.RuleRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 规则服务
 * 提供规则管理的业务逻辑
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RuleService {
    
    private final RuleRepository ruleRepository;
    
    /**
     * 获取规则详情
     */
    public Rule getRule(Long ruleId) {
        return ruleRepository.findById(ruleId)
                .orElseThrow(() -> new RuntimeException("规则不存在: " + ruleId));
    }
    
    /**
     * 根据名称获取规则
     */
    public Rule getRuleByName(String name) {
        return ruleRepository.findByName(name)
                .orElseThrow(() -> new RuntimeException("规则不存在: " + name));
    }
    
    /**
     * 获取所有规则
     */
    public Page<Rule> getAllRules(Pageable pageable) {
        return ruleRepository.findAll(pageable);
    }
    
    /**
     * 根据分类获取规则
     */
    public List<Rule> getRulesByCategory(String category) {
        return ruleRepository.findByCategory(category);
    }
    
    /**
     * 根据优先级获取规则
     */
    public List<Rule> getRulesByPriority(RulePriority priority) {
        return ruleRepository.findByPriority(priority);
    }
    
    /**
     * 获取启用的规则
     */
    public List<Rule> getEnabledRules() {
        return ruleRepository.findByEnabledTrue();
    }
    
    /**
     * 获取禁用的规则
     */
    public List<Rule> getDisabledRules() {
        return ruleRepository.findByEnabledFalse();
    }
    
    /**
     * 获取有效规则
     */
    public List<Rule> getValidRules() {
        return ruleRepository.findValidRules(LocalDateTime.now());
    }
    
    /**
     * 根据分类获取有效规则
     */
    public List<Rule> getValidRulesByCategory(String category) {
        return ruleRepository.findValidRulesByCategory(category, LocalDateTime.now());
    }
    
    /**
     * 获取按优先级排序的启用规则
     */
    public List<Rule> getEnabledRulesOrderByPriority() {
        return ruleRepository.findEnabledRulesOrderByPriority();
    }
    
    /**
     * 根据分类获取按优先级排序的启用规则
     */
    public List<Rule> getEnabledRulesByCategoryOrderByPriority(String category) {
        return ruleRepository.findEnabledRulesByCategoryOrderByPriority(category);
    }
    
    /**
     * 获取高优先级规则
     */
    public List<Rule> getHighPriorityRules() {
        List<RulePriority> highPriorities = List.of(
                RulePriority.HIGH, 
                RulePriority.URGENT, 
                RulePriority.CRITICAL
        );
        return ruleRepository.findHighPriorityRules(highPriorities);
    }
    
    /**
     * 获取最近执行的规则
     */
    public List<Rule> getRecentlyExecutedRules(Pageable pageable) {
        return ruleRepository.findRecentlyExecutedRules(pageable);
    }
    
    /**
     * 获取高成功率规则
     */
    public List<Rule> getHighSuccessRateRules(double successRateThreshold) {
        return ruleRepository.findHighSuccessRateRules(successRateThreshold);
    }
    
    /**
     * 获取低成功率规则
     */
    public List<Rule> getLowSuccessRateRules(long minExecutions, double successRateThreshold) {
        return ruleRepository.findLowSuccessRateRules(minExecutions, successRateThreshold);
    }
    
    /**
     * 获取从未执行过的规则
     */
    public List<Rule> getNeverExecutedRules() {
        return ruleRepository.findByExecutionCount(0L);
    }
    
    /**
     * 获取长时间未执行的规则
     */
    public List<Rule> getStaleRules(int daysThreshold) {
        LocalDateTime threshold = LocalDateTime.now().minusDays(daysThreshold);
        return ruleRepository.findStaleRules(threshold);
    }
    
    /**
     * 根据版本获取规则
     */
    public List<Rule> getRulesByVersion(String version) {
        return ruleRepository.findByRuleVersion(version);
    }
    
    /**
     * 获取即将过期的规则
     */
    public List<Rule> getExpiringRules(int daysThreshold) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime threshold = now.plusDays(daysThreshold);
        return ruleRepository.findExpiringRules(now, threshold);
    }
    
    /**
     * 搜索规则
     */
    public List<Rule> searchRules(String keyword) {
        return ruleRepository.findByKeyword(keyword);
    }
    
    /**
     * 删除规则
     */
    @Transactional
    public void deleteRule(Long ruleId) {
        log.info("删除规则 - ID: {}", ruleId);
        
        Rule rule = getRule(ruleId);
        ruleRepository.delete(rule);
        
        log.info("规则删除成功 - ID: {}, 名称: {}", ruleId, rule.getName());
    }
    
    /**
     * 批量删除规则
     */
    @Transactional
    public void deleteRules(List<Long> ruleIds) {
        log.info("批量删除规则 - 数量: {}", ruleIds.size());
        
        for (Long ruleId : ruleIds) {
            try {
                deleteRule(ruleId);
            } catch (Exception e) {
                log.error("删除规则失败 - ID: {}", ruleId, e);
            }
        }
    }
    
    /**
     * 统计分类下的规则数量
     */
    public long countRulesByCategory(String category) {
        return ruleRepository.countByCategory(category);
    }
    
    /**
     * 统计启用的规则数量
     */
    public long countEnabledRules() {
        return ruleRepository.countByEnabledTrue();
    }
    
    /**
     * 统计特定优先级的规则数量
     */
    public long countRulesByPriority(RulePriority priority) {
        return ruleRepository.countByPriority(priority);
    }
    
    /**
     * 检查规则名称是否存在
     */
    public boolean existsByName(String name) {
        return ruleRepository.findByName(name).isPresent();
    }
    
    /**
     * 获取规则执行统计
     */
    public RuleExecutionStatistics getRuleExecutionStatistics(Long ruleId) {
        Rule rule = getRule(ruleId);
        
        RuleExecutionStatistics stats = new RuleExecutionStatistics();
        stats.setRuleId(ruleId);
        stats.setRuleName(rule.getName());
        stats.setExecutionCount(rule.getExecutionCount());
        stats.setSuccessCount(rule.getSuccessCount());
        stats.setSuccessRate(rule.getSuccessRate());
        stats.setLastExecutedAt(rule.getLastExecutedAt());
        stats.setLastSuccessAt(rule.getLastSuccessAt());
        
        return stats;
    }
    
    /**
     * 获取所有规则的执行统计
     */
    public List<RuleExecutionStatistics> getAllRuleExecutionStatistics() {
        List<Rule> rules = ruleRepository.findAll();
        
        return rules.stream()
                .map(rule -> {
                    RuleExecutionStatistics stats = new RuleExecutionStatistics();
                    stats.setRuleId(rule.getId());
                    stats.setRuleName(rule.getName());
                    stats.setExecutionCount(rule.getExecutionCount());
                    stats.setSuccessCount(rule.getSuccessCount());
                    stats.setSuccessRate(rule.getSuccessRate());
                    stats.setLastExecutedAt(rule.getLastExecutedAt());
                    stats.setLastSuccessAt(rule.getLastSuccessAt());
                    return stats;
                })
                .toList();
    }
    
    /**
     * 重置规则执行统计
     */
    @Transactional
    public void resetRuleExecutionStatistics(Long ruleId) {
        log.info("重置规则执行统计 - ID: {}", ruleId);
        
        Rule rule = getRule(ruleId);
        rule.setExecutionCount(0L);
        rule.setSuccessCount(0L);
        rule.setLastExecutedAt(null);
        rule.setLastSuccessAt(null);
        
        ruleRepository.save(rule);
        
        log.info("规则执行统计重置成功 - ID: {}", ruleId);
    }
    
    /**
     * 批量重置规则执行统计
     */
    @Transactional
    public void resetAllRuleExecutionStatistics() {
        log.info("重置所有规则执行统计");
        
        List<Rule> rules = ruleRepository.findAll();
        
        for (Rule rule : rules) {
            rule.setExecutionCount(0L);
            rule.setSuccessCount(0L);
            rule.setLastExecutedAt(null);
            rule.setLastSuccessAt(null);
        }
        
        ruleRepository.saveAll(rules);
        
        log.info("所有规则执行统计重置完成 - 数量: {}", rules.size());
    }
    
    // 内部类定义
    public static class RuleExecutionStatistics {
        private Long ruleId;
        private String ruleName;
        private Long executionCount;
        private Long successCount;
        private double successRate;
        private LocalDateTime lastExecutedAt;
        private LocalDateTime lastSuccessAt;
        
        // getters and setters
        public Long getRuleId() { return ruleId; }
        public void setRuleId(Long ruleId) { this.ruleId = ruleId; }
        public String getRuleName() { return ruleName; }
        public void setRuleName(String ruleName) { this.ruleName = ruleName; }
        public Long getExecutionCount() { return executionCount; }
        public void setExecutionCount(Long executionCount) { this.executionCount = executionCount; }
        public Long getSuccessCount() { return successCount; }
        public void setSuccessCount(Long successCount) { this.successCount = successCount; }
        public double getSuccessRate() { return successRate; }
        public void setSuccessRate(double successRate) { this.successRate = successRate; }
        public LocalDateTime getLastExecutedAt() { return lastExecutedAt; }
        public void setLastExecutedAt(LocalDateTime lastExecutedAt) { this.lastExecutedAt = lastExecutedAt; }
        public LocalDateTime getLastSuccessAt() { return lastSuccessAt; }
        public void setLastSuccessAt(LocalDateTime lastSuccessAt) { this.lastSuccessAt = lastSuccessAt; }
    }
}